package com.budwk.app.sqfwV2.service.meeting;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.common.config.AppException;
import com.budwk.app.jim.SqfwWebSocket;
import com.budwk.app.jim.WebSocketMsgDTO;
import com.budwk.app.sqfw.component.FromSummaryComponent;
import com.budwk.app.sqfw.constants.SqfwFormSummaryConstants;
import com.budwk.app.sqfw.constants.SqfwWebSocketMsgConstants;
import com.budwk.app.sqfw.enums.DownLoadFileNameEnum;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.Sqfw_completeflow;
import com.budwk.app.sqfw.models.Sqfw_formSummary;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwCompleteflowService;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfw.vo.GenerateWordAndPdfUrlVO;
import com.budwk.app.sqfwDoc.codeGenerator.impl.SqfwTemplatePdfCommonService;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.AbstractCustomerPdfCreateField;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.BasePdfParamDTO;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.BaseTemplatePdfGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.SqfwPdfCreateCommonBO;
import com.budwk.app.sqfwV2.dto.MeetingParamDTO;
import com.budwk.app.sqfwV2.enums.MeetingEnums;
import com.budwk.app.sqfwV2.generator.meeting.MeetingPdfGenerator;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.security.utils.SecurityUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.stream.Collectors;

import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.generateWordDocument;
import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.wordToPdfAndUpload;

/**
 * 本代码由代码生成器生成，版本号1.0
 */
@Slf4j
@IocBean
public class MeetingPdfService extends SqfwTemplatePdfCommonService {

    @Inject
    private SqfwCompleteflowService sqfwCompleteflowService;
    @Inject
    private SqfwFormsummaryNewService sqfwFormsummaryNewService;

    @Inject
    private FromSummaryComponent fromSummaryComponent;

    @Inject
    private SysUserService userService;
    /*
    protected  List<BaseTemplatePdfGenerator> generatorList = Collections.synchronizedList(new ArrayList<>());
    */
    protected static BlockingQueue<BaseTemplatePdfGenerator> generatorQueue = new ArrayBlockingQueue<>(100);

    @Override
    public AbstractCustomerPdfCreateField getPdfCreateField(Sqfw_formSummary_new formSummary) {
        return JSONObject.parseObject(formSummary.getParamData(), MeetingParamDTO.class);
    }

    /**
     * 第五张表中的需要的类型，详情见 {@link SqfwFormSummaryConstants}
     *
     * @return 返回数据
     */
    @Override
    public String getSummaryType() {
        return SupportBusinessTypeEnum.MEETING_ACTIVITY_VISIT_RECORD.getCode();
    }


    public MeetingPdfService addGeneratorQueue(BaseTemplatePdfGenerator generator) {
        generatorQueue.offer(generator);
        return this;
    }

    /**
     * 当pdf生成成功的时候，sock发送什么样的消息至前端
     * 参照{@link SqfwWebSocketMsgConstants}
     *
     * @return 结果
     */
    @Override
    public String getPdfCreateSocketType() {
        return SqfwWebSocketMsgConstants.WORK_FORM_MEET_RECORD_PDF_RECREATED;
    }

    /**
     * 创建下载文件的名称
     * 可以参照 {@link com.budwk.app.sqfw.enums.DownLoadFileNameEnum}
     * 注意！！！ 不用加上.pdf或者.word后缀
     *
     * @param completeFlow   工作流
     * @param formSummaryNew 表单数据
     * @return 结果
     */
    @Override
    protected String getDownloadFileName(Sqfw_completeflow completeFlow, Sqfw_formSummary_new formSummaryNew) {
       /* MeetingParamDTO meetingParamDTO = JSONUtil.toBean(formSummaryNew.getParamData(), MeetingParamDTO.class);
        String fileName = meetingParamDTO.getTheme() + "&" + DateUtil.format(new Date(), "yyyyMMdd");
        return fileName;*/
        return completeFlow.getText();
    }

    @Override
    protected void customerPopularPdfCreateParam(SqfwPdfCreateCommonBO pdfCreateCommonBO, Sqfw_completeflow completeFlow, Sqfw_formSummary_new formSummary) {

    }

    @Override
    protected List<BaseTemplatePdfGenerator> getPdfGenerator(Sqfw_completeflow completeFlow, Sqfw_formSummary_new formSummary) {
        BaseTemplatePdfGenerator generator = generatorQueue.poll();
        List<BaseTemplatePdfGenerator> generatorList = Lists.newArrayList();
        generatorList.add(generator);
        return generatorList;
    }


    public Result<?> afreshGeneratePDF(String completeflowId) {
        Sqfw_completeflow completeFlow = sqfwCompleteflowService.fetch(completeflowId);
        if (completeFlow == null) {
            throw new AppException("任务流数据不存在");
        }
        Sqfw_formSummary_new formSummary = sqfwFormsummaryNewService.fetch(Cnd.where(Sqfw_formSummary::getSqfwFlowId, "=", completeFlow.getId()));
        if (formSummary == null) {
            throw new AppException("数据不存在");
        }
        MeetingParamDTO meetingParamDTO = JSONObject.parseObject(formSummary.getParamData(), MeetingParamDTO.class);
        addGeneratorQueue(new MeetingPdfGenerator(MeetingEnums.getTemplatName(meetingParamDTO.getType())));
        String userId = SecurityUtil.getUserId();
        //super.generatePdfByFlowAndForm(userId,completeflow,formSummary);

        SqfwWebSocket sqfwWebSocket = NutzIocUtils.getBean(SqfwWebSocket.class);

        SqfwPdfCreateCommonBO pdfCreateCommonBO = new SqfwPdfCreateCommonBO();

        // 设置一些基础的信息
        BasePdfParamDTO basePdfParamDTO = new BasePdfParamDTO();
        BeanUtil.copyProperties(formSummary, basePdfParamDTO);
        basePdfParamDTO.setCreateUserId(formSummary.getCreateBy());
        basePdfParamDTO.setFormSummaryTypeCode(getSummaryType());
        basePdfParamDTO.setCreateUserName(formSummary.getCreateUserName());
        basePdfParamDTO.setCreateUserPhone(formSummary.getCreateUserPhone());
        basePdfParamDTO.setCreateUserSigUrl(userService.fetch(userId).getSignatureUrl());
        basePdfParamDTO.setSqfwId(completeFlow.getSqfwId());

        Date fillDate = formSummary.getFillDate();
        if (fillDate == null) fillDate = formSummary.getCreateDate();
        basePdfParamDTO.setFillDate(fillDate);
        basePdfParamDTO.setProvince(formSummary.getProvince());
        basePdfParamDTO.setCity(formSummary.getCity());
        basePdfParamDTO.setDistrict(formSummary.getDistrict());
        basePdfParamDTO.setCounty(formSummary.getCounty());
        basePdfParamDTO.setCommunity(formSummary.getCommunity());

        pdfCreateCommonBO.setBasePdfParamDTO(basePdfParamDTO);

        AbstractCustomerPdfCreateField pdfField = getPdfCreateField(formSummary);
        pdfCreateCommonBO.setAbstractCustomerPdfCreateField(pdfField);

        customerPopularPdfCreateParam(pdfCreateCommonBO, completeFlow, formSummary);

        try {
            List<BaseTemplatePdfGenerator> generatorList = getPdfGenerator(completeFlow, formSummary);

            List<ByteArrayOutputStream> osList = Lists.newArrayList();

            for (BaseTemplatePdfGenerator generator : generatorList) {
                XWPFTemplate pdfTemplate = generator.createPdf(pdfCreateCommonBO);
                // 生成pdf后的操作
                ByteArrayOutputStream pdfOS = generator.generatePDFAfter(pdfTemplate, formSummary);
                if (pdfOS == null) {
                    pdfOS = new ByteArrayOutputStream();
                    pdfTemplate.write(pdfOS);
                }
                if (pdfOS != null) osList.add(pdfOS);
            }

            String fileName = getDownloadFileName(completeFlow, formSummary);
            GenerateWordAndPdfUrlVO wordVO = wordToPdfAndUpload(osList, fileName, formSummary.getUnitName() + formSummary.getType());

            if (StringUtils.isBlank(wordVO.getPdfUrl())) {
                completeFlow.setResourcePath("error");
            } else {
                completeFlow.setResourcePath(wordVO.getPdfUrl());
                sqfwCompleteflowService.update(completeFlow);

                // 发送一个websocket通知前端
                WebSocketMsgDTO msgDTO = new WebSocketMsgDTO();
                msgDTO.setType(getPdfCreateSocketType());
                msgDTO.setMsg("PDF生成成功");
                sqfwWebSocket.sendMessage(userId, msgDTO);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("创建PDF失败");
            completeFlow.setResourcePath("error");
            sqfwCompleteflowService.update(completeFlow);
        }
        return Result.success();
    }

    public String generatePDF(Integer templateCode, boolean isTemplate, String userId, String sqwfIds,boolean isAdmin) {
        if (isTemplate) {
            //下载模板
            return downLoadTemplate();
        }
        if (StringUtils.isBlank(sqwfIds)) return null;
        Cnd cnd = Cnd.NEW();
        if(isAdmin){
            Cnd summaryCnd = Cnd.NEW();
            summaryCnd.and("id","in",Lists.newArrayList(sqwfIds.split(",")));
            List<Sqfw_formSummary_new> sqfwFormSummaryNewList = sqfwFormsummaryNewService.query(summaryCnd);
            List<String> ids = sqfwFormSummaryNewList.stream().map(Sqfw_formSummary_new::getSqfwFlowId).distinct().collect(Collectors.toList());
            cnd.and("id", "in", ids);
        }else{
            cnd.and("sqfw_id", "in", Lists.newArrayList(sqwfIds.split(",")));
        }
        cnd.orderBy("create_date", "asc");
        List<Sqfw_completeflow> completeFlowList = sqfwCompleteflowService.query(cnd);
        if (completeFlowList.size() == 0) return null;
        List<String> pdfList = completeFlowList.stream().map(Sqfw_completeflow::getResourcePath).collect(Collectors.toList());
        try {
            String fileName = DownLoadFileNameEnum.MEETING_DOCX_SUMMARY.getName() + "&" + DateUtil.format(new Date(), "yyyyMMddHHmmss");
            return CommonFormOfficeUtils.createConvergePdfAndUpload(pdfList, fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private String downLoadTemplate() {
        //Sys_user user= userService.getUserById(SecurityUtil.getUserId());
        Map<String,Object>  map = new HashMap<>();
        map.put("county",null);
        map.put("community","社区");
        map.put("createUserName",null);
        map.put("fillDateStr","年  月  日");
        map.put("theme",null);
        map.put("presentMembers",null);
        map.put("needNum",null);
        map.put("actNum",null);
        map.put("address",null);
        map.put("meetingContent",null);
        map.put("images",null);
        map.put("imagess",null);
        map.put("unit",null);

        List<NiceXWPFDocument> documents = new ArrayList<>();
        //会议记录
        XWPFTemplate meeyingTemplate = generateWordDocument(map, null, MeetingEnums.MEETING_MINUTES_DOCX.getTemplat());
        documents.add(meeyingTemplate.getXWPFDocument());
        //活动记录
        XWPFTemplate activityTemplate = generateWordDocument(map, null, MeetingEnums.ACTIVITIES_DOCX.getTemplat());
        documents.add(activityTemplate.getXWPFDocument());
        //来访记录
        XWPFTemplate visitTemplate = generateWordDocument(map, null, MeetingEnums.VISITING_RECORDS_DOCX.getTemplat());
        documents.add(visitTemplate.getXWPFDocument());
        GenerateWordAndPdfUrlVO vo = CommonFormOfficeUtils.wordUpload(documents, DownLoadFileNameEnum.MEETING_DOCX_SUMMARY.getName() + "&" + DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        return vo.getWordUrl();
    }
}
